Tip Corner: Using Variables with Graphics and Text Commands

© 2004, Brad Moore

author website:

http://www.freewebs.com/lb-connection

Home

Tip Corner

API Corner

Just for fun

Timing Events

QCard Lesson

Menus: Checkmarks

Dissolve Demo

Encryption

Poker Game

Snip Manager

Demos

Newsletter help

Index


One of the unique things about Liberty Basic is the syntax structure for GUI and Graphics commands. Components get and receive commands using the PRINT and INPUT statements. This also applies to graphics commands, as they are essentially GUI commands directed at a graphicbox GUI component. A example of this format is the following statement which draws a box in a graphicbox:


print #main.gb, "box 30 30"

Examining this statement we notice it begins with a PRINT command. The nature of the command is one of direction. PRINT sends output to something. The next element in the command defines who gets the subsequent output string. This is the handle of the GUI component. In the case of the statement above it is a graphicbox called "gb" which is part of a window called "#main". The last element of the statement is the command string that is being sent to the GUI component by the print statement. Notice that it is a quoted string.

In the case of the statement above, we are telling Liberty Basic to create a 30 pixel by 30 pixel box at the current pen location. Every time this statement is executed, it will create a 30 x 30 box. Obviously we could create any size box by simply changing the value of the box parameters from 30 30 to some other values. But what if we did not know what the actual values were before the program ran? What if the user decided what size to make the box when the program was running? In this case, we would not be able to simply set a given size; we would have to use a variable.

This is the difference between design time definition (where the size and location is fixed) and runtime definition, where the user decides what and where a component should be placed or defined.

Suppose we obtained the size of the box and assigned the x and y values to the variables "sizex" and "sizey". We might be tempted to try something like:


sizex = 50
sizey = 80
print #main.gb, "box sizex sizey"

Unfortunately, this will not yield the desired results. Suppose the user decided on a 50 by 80 box. Our code as it is would draw a box 0 x 0. But why? The reason lay in the structure of the statement as we outlined above. The entire command to be sent to the GUI component must be a string. We have followed that rule; however what we defined was a string literal - a sting whose value never changes. There are no dynamic components in the string. For it to be dynamic it would have to contain a variable! "But wait", you say, "Isn't sizex and sizey variables?"

Well, they are OUTSIDE of the string, but with in the limits of the quote marks, they are simply text. They evaluate to zeros for the purpose of the box command. In order to pass the desired values to the box command, we must dynamically build the command string. This is done using some simple string concatenation and string commands.

We use the STR$ function to convert a numeric variable to a string variable of the same value. It works like this:


A$ = STR$(25)

After being executed A$ will contain "25".

What we need to do is dynamically create a string the will look like the following at runtime:


"box 50 80"

We do this by starting with the "box" command


A$ = "box "

Notice that a space character follows the word box. Spaces are important to Liberty Basic's parser. Errors will occur if you omit them. Now we will add the "sizex" variable:


A$ = "box " + str$(sizex)

If we were to examine A$ at runtime it would look like this:


"box 50"

Remember the spaces. We need to add a space to separate the x and y values for the box command. That is done like this:


A$ = "box " + str$(sizex) + " "

Finally, add the "sizey" value to the string:


A$ = "box " + str$(sizex) + " " + str$(sizey)

Now we can simply print A$ to the GUI component in a statement such as:


sizex = 50
sizey = 80
A$ = "box " + str$(sizex) + " " + str$(sizey)
Print #main.gb, A$

This is one way of building a dynamic string to send dynamic values to GUI components during runtime. There is another way of accomplishing the same results with a little less code. It requires building the dynamic string as a part of the print statement. The important difference when doing it this way is that you can only send a single string value, so concatenation with the "+" (plus) operator is not possible. Instead, the string is concatenated with the semicolon. It is important to remember the required space in this format also. Here is the same code fragment using this technique. You should easily be able to identify each segment of the dynamic string:


sizex = 50
sizey = 80
Print #main.gb, "box ";str$(sizex);" ";str$(sizey)

In the format above, the STR$ function is not required, as numeric values and strings can be concatenated in this form without special consideration of the variable type. When you concatenate using the "+" (plus) operator you MUST convert all the variables to string types. As a result we could further simplify the print statement above:


Print #main.gb, "box ";sizex;" ";sizey

These procedures can be (and should be) applied to both graphics commands and text commands where dynamic values are required.

I frequently see people asking why the following code (or something like it) did not work:


sizex = 50
sizey = 80
print #main.gb, "box sizex sizey"

In fact I have sat and scratched my head wondering the very same question, staring at some code and trying to figure out why something did not work. It almost always boils down to improper format using variables in string literal, rather than dynamically building the string to be passed to the control.

Let me just mention also, in Liberty Basic 3.0 and higher, it is not necessary to use the PRINT statement to accomplish the tasks above. You can simply specify the handle of the control and the command string. The PRINT is assumed. Here is our statement further simplified:


sizex = 50
sizey = 80
#main.gb "box ";sizex;" ";sizey

Here is a simple (and fun) demo program that shows these concepts in practice. Have fun!



dim color$(16)
for x = 1 to 16
    read a$
    color$(x) = a$
next x


    NOMAINWIN
    WindowWidth = 354 : WindowHeight = 317
    UpperLeftX = INT((DisplayWidth-WindowWidth)/2)
    UpperLeftY = INT((DisplayHeight-WindowHeight)/2)


graphicbox  #main.gb, 10, 15, 325, 240

Open "Wow!" for Window as #main

    #main "trapclose [quit]"
    #main.gb "down; fill Yellow; flush"
    #main "font ms_sans_serif 10"

    for x = 1 to 250
        'choose random locations for x and y locations to draw at
        locx = int(rnd(0)*250)+1
        locy = int(rnd(0)*200)+1
        #main.gb "up; goto ";locx;" ";locy;"; down"
        'choose random color and size for box
        color = int(rnd(0)*16)+1 
        sizex = int(rnd(0)*280)+40
        sizey = int(rnd(0)*190)+40
        #main.gb "backcolor ";color$(color)
        #main.gb "boxfilled ";sizex;" ";sizey
        call Sleep 50
        scan
    next x

    Wait

[quit]
    close #main : END
    
Sub Sleep value
    CallDLL #kernel32, "Sleep",value As Long,r As Void
    End Sub
    

data black, blue, brown, cyan, darkblue, darkred, green
data darkcyan, darkgray, darkgreen, darkpink, lightgray
data palegray, pink, red, white


Home

Tip Corner

API Corner

Just for fun

Timing Events

QCard Lesson

Menus: Checkmarks

Dissolve Demo

Encryption

Poker Game

Snip Manager

Demos

Newsletter help

Index